---
slug: fileupload-download
title: 2. 文件上传下载
author: dotNET China
author_title: 让 .NET 开发更简单，更通用，更流行。
author_url: https://www.chinadot.net
author_image_url: https://i.loli.net/2021/01/19/M8q5a3OTZWUKicl.png
tags: [furion, furos, .net, .netcore, .net5, upload, download]
---

import useBaseUrl from "@docusaurus/useBaseUrl";

## 文件下载

```cs
[HttpGet, NonUnify]
public IActionResult FileDownload(string path, string fileName)
{
    string filePath = "这里获取完整的文件下载路径";
    return new FileStreamResult(new FileStream(filePath, FileMode.Open), "application/octet-stream") { FileDownloadName = fileName };
}
```

:::note 关于前端获取文件名

如果前端获取不到文件夹，可添加以下配置：

```cs
_httpContextAccessor.HttpContext.Response.Headers.Add("Content-Disposition", $"attachment; filename={文件名}");
_httpContextAccessor.HttpContext.Response.Headers.Add("Access-Control-Expose-Headers", "Content-Disposition");
```

:::

<!--truncate-->

## 文件上传

```cs
[HttpPost, NonUnify]
public async Task<IActionResult> UploadFileAsync(List<IFormFile> files)
{
    // 保存到网站根目录下的 uploads 目录
    var savePath = Path.Combine(App.HostEnvironment.ContentRootPath, "uploads");
    if(!Directory.Exists(savePath)) Directory.CreateDirectory(savePath);

    long size = files.Sum(f => f.Length);

    foreach (var formFile in files)
    {
        if (formFile.Length > 0)
        {
            // 避免文件名重复，采用 GUID 生成
            var filePath = Path.Combine(savePath, Guid.NewGuid().ToString("N") + Path.GetExtension(formFile.FileName));  // 可以替代为你需要存储的真实路径

            using (var stream = System.IO.File.Create(filePath))
            {
                await formFile.CopyToAsync(stream);
            }
        }
    }

    // 在动态 API 直接返回对象即可，无需 OK 和 IActionResult
    return Ok(new { count = files.Count, size });
}
```
